Imports Microsoft.VisualBasic
Imports System
Imports System.IO
Imports System.Reflection
Imports System.ComponentModel
Imports System.Drawing
Imports System.Collections.Generic
Imports System.Windows.Forms
Imports C4F.DevKit.PreviewHandler.PreviewHandlerFramework

Namespace C4F.DevKit.PreviewHandler.PreviewHandlerHost
    ''' <summary>
    ''' This control is dependent on the managed framework for preview handlers implemented by Stephen Toub
    ''' and published in the December 2006 issue of MSDN Magazine.  http://msdn.microsoft.com/msdnmag/issues/07/01/PreviewHandlers/default.aspx
    ''' In this article, he implements a managed wrapper to the COM Preview Handler interfaces IPreviewHandler, IInitializeWithFile and IInitializeWithStream
    ''' 
    ''' In this class, we look up the registered preview handler for a given file extension, using reflection, instantiate an instance of the handler.
    ''' We then check if the handler is a Stream or File Handler by checking which interface is implemented.  We then initialize the handler, pass a handle to 
    ''' our control and the bounds of our control, and call DoPreview (part of the IPreviewHandler interface)
    '''
    ''' Developed by Ryan Powers - Clarity Consulting http://www.claritycon.com
    ''' </summary>
    <ToolboxItem(True), ToolboxBitmap(GetType(PreviewHandlerHostControl))> _
    Partial Public Class PreviewHandlerHostControl
        Inherits UserControl
        Private _filePath As String
        Private _comInstance As Object = Nothing

        Public Sub New()
            InitializeComponent()
        End Sub

        ''' <summary>
        ''' Full path to file to be previewed
        ''' 
        ''' Whenever a new path is set, the preview is generated
        ''' </summary>
        Public Property FilePath() As String
            Get
                Return _filePath
            End Get
            Set(ByVal value As String)
                _filePath = value
                If Not value Is Nothing Then
                    GeneratePreview()
                End If
            End Set
        End Property


        ''' <summary>
        ''' 1) Look up the preview handler associated with the file extension
        ''' 2) Create an instance of the handler using its CLSID and reflection
        ''' 3) Check if it is a file or stream handler
        ''' 4) Initialize with File or Stream using Initialize from the appropriate interface
        ''' 5) Call SetWindow passing in a handle to this control and the bounds of the control
        ''' 6) Call DoPreview
        ''' </summary>
        Private Sub GeneratePreview()
            lblMessage.Visible = False
            If Not _comInstance Is Nothing Then
                CType(_comInstance, IPreviewHandler).Unload()
            End If

            Dim r As RECT
            r.top = 0
            r.bottom = Me.Height
            r.left = 0
            r.right = Me.Width

            Dim data As RegistrationData = PreviewHandlerRegistryAccessor.LoadRegistrationInformation()
            Dim handler As PreviewHandlerInfo = Nothing

            For Each ei As ExtensionInfo In data.Extensions
                If _filePath.ToUpper().EndsWith(ei.Extension.ToUpper()) Then
                    handler = ei.Handler
                    If Not handler Is Nothing Then
                        Exit For
                    End If
                End If
            Next ei
            If handler Is Nothing Then
                lblMessage.Visible = True
                lblMessage.Text = "No Preview Available"
                Return
            End If

            Dim comType As Type = Type.GetTypeFromCLSID(New Guid(handler.ID))
            Try
                ' Create an instance of the preview handler
                _comInstance = Activator.CreateInstance(comType)

                ' Check if it is a stream or file handler
                If TypeOf _comInstance Is IInitializeWithFile Then
                    CType(_comInstance, IInitializeWithFile).Initialize(_filePath, 0)
                ElseIf TypeOf _comInstance Is IInitializeWithStream Then
                    If File.Exists(_filePath) Then
                        Dim stream As StreamWrapper = New StreamWrapper(File.Open(_filePath, FileMode.Open))
                        CType(_comInstance, C4F.DevKit.PreviewHandler.PreviewHandlerFramework.IInitializeWithStream).Initialize(stream, 0)
                    Else
                        Throw New Exception("File not found")
                    End If
                End If
                CType(_comInstance, IPreviewHandler).SetWindow(Me.Handle, r)
                CType(_comInstance, IPreviewHandler).DoPreview()
            Catch ex As Exception
                _comInstance = Nothing
                lblMessage.Visible = True
                lblMessage.Text = "Preview Generation Failed - " & ex.Message
            End Try

        End Sub

        ''' <summary>
        ''' When the control loads, generate a preview if we have an initial file path
        ''' </summary>
        Private Sub Control_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
            If Not _filePath Is Nothing Then
                GeneratePreview()
            End If

        End Sub

        Private Sub Control_Resize(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Resize
            If Me._comInstance IsNot Nothing Then
                Dim r As RECT
                r.top = 0
                r.bottom = Me.Height
                r.left = 0
                r.right = Me.Width

                CType(_comInstance, IPreviewHandler).SetRect(r)

            End If
        End Sub
    End Class
End Namespace